package com.elvis.chat.utils.add;

import com.elvis.chat.ui.XMPPErrorType;

import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.packet.DelayInformation;

import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;

import java.io.IOException;
import java.util.Date;

/**
 * This class represents a instant message.
 * @author darisk
 */
public class MessageInfo implements Parcelable {

    /** Parcelable.Creator needs by Android. */
    public static final Parcelable.Creator<MessageInfo> CREATOR = new Parcelable.Creator<MessageInfo>() {

	@Override
	public MessageInfo createFromParcel(Parcel source) {
	    return new MessageInfo(source);
	}

	@Override
	public MessageInfo[] newArray(int size) {
	    return new MessageInfo[size];
	}
    };

    private long mId;
    private String mMsgId;
    private int mBoxType;
    private int mChatType;
    private int mStatusType;
    private int mBodyType;
    private String mBody;
    private String mSubject;
    private String mTo;
    private String mFrom;
    private String mThread;
    private Date mSentDate;
    private Date mReceivedDate;
    private boolean mHL;

    private int mError;
    private String mDevices;
    private int mRead;

    private AttachmentInfo mAttachment;

    /**
     * Constructor.
     * @param to the destinataire of the message
     * @param type the message type
     */
    public MessageInfo(final String to, final int type) {
	mTo = to;
	mChatType = type;
	mStatusType = MessageStatusType.MSG_STATUS_NORMAL;
	mBodyType = MessageBodyType.MSG_BODY_TYPE_TEXT;
	mBody = "";
	mSubject = "";
	mThread = "";
	mFrom = null;
	mSentDate = new Date();
	mReceivedDate = new Date();
	mHL = false;
	mRead = MessageReadType.MESSAGE_TYPE_UNREAD;
	mError = XMPPErrorType.NoError;
	mDevices = "";
    }

    /**
     * Constructor a message of type chat.
     * @param to the destinataire of the message
     */
    public MessageInfo() {
	this(null, MessageChatType.MSG_TYPE_CHAT);
    }

    /**
     * Constructor a message of type chat.
     * @param to the destinataire of the message
     */
    public MessageInfo(final String to) {
	this(to, MessageChatType.MSG_TYPE_CHAT);
    }

    /**
     * Construct a message from a smack message packet.
     * @param smackMsg Smack message packet
     */
    public MessageInfo(final org.jivesoftware.smack.packet.Message smackMsg) {
	this(smackMsg.getTo());
	try {
	    mId = Long.parseLong(smackMsg.getPacketID());
	} catch (Exception e) {
	    e.printStackTrace();
	    mId = IdUtils.getInstanse().getUID();
	}

	mChatType = MessageChatType.getMessageType(smackMsg);
	this.mFrom = smackMsg.getFrom();
	mHL = false;
	if (mChatType == MessageChatType.MSG_TYPE_ERROR) {
	    XMPPError er = smackMsg.getError();
	    String msg = er.getMessage();
	    if (msg != null)
		mBody = msg;

	    mError = XMPPErrorType.getErrorType(er.getCondition());
	} else {
	    mBody = smackMsg.getBody();
	    mSubject = smackMsg.getSubject();
	    mThread = smackMsg.getThread();
	}
	PacketExtension pTime = smackMsg.getExtension("delay", "urn:xmpp:delay");
	if (pTime instanceof DelayInformation) {
	    mSentDate = mReceivedDate = ((DelayInformation) pTime).getStamp();
	} else {
	    mSentDate = mReceivedDate = new Date();
	}
	addAttachment(smackMsg);
    }

    /* ==============Add by kexuejin======== */
    private void addAttachment(final org.jivesoftware.smack.packet.Message smackMsg) {
	PacketExtension attachmentExt = smackMsg.getExtension(AttachmentExtension.ELEMENT_NAME,
	    AttachmentExtension.NAMESPACE);
	if (attachmentExt != null) {
	    AttachmentManager manager = new AttachmentManager();
	    mAttachment = manager.loadAttachment(attachmentExt.toXML());
	    String mimeType = mAttachment.getMimeType();
	    mBodyType = MessageBodyType.getBodyType(mimeType);
	    mStatusType = MessageStatusType.MSG_STATUS_WAIT_DOWN;

	    try {
		String filePath = Environment.getExternalStorageDirectory().getCanonicalPath() + FileUtil.BASEDIR;
		if (FileUtil.isAudioType(mimeType)) {
		    filePath += "attachment/audio/";
		} else if (FileUtil.isImageType(mimeType)) {
		    filePath += "attachment/image/";
		} else if (FileUtil.isVideoType(mimeType)) {
		    filePath += "attachment/video/";
		} else {
		    filePath += "attachment/other/";
		}
		filePath += mAttachment.getFileName();
		mAttachment.setFilePath(filePath);
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}

    }

    /* ==============End======== */
    /**
     * Construct a message from a parcel.
     * @param in parcel to use for construction
     */
    private MessageInfo(final Parcel in) {
	mId = in.readLong();
	mBoxType = in.readInt();
	mChatType = in.readInt();
	mStatusType = in.readInt();
	mTo = in.readString();
	mBody = in.readString();
	mSubject = in.readString();
	mThread = in.readString();
	mFrom = in.readString();
	mSentDate = new Date(in.readLong());
	mReceivedDate = new Date(in.readLong());
	mHL = false;
	mRead = in.readInt();
	mDevices = in.readString();
	mError = in.readInt();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
	dest.writeLong(mId);
	dest.writeInt(mBoxType);
	dest.writeInt(mChatType);
	dest.writeInt(mStatusType);
	dest.writeString(mTo);
	dest.writeString(mBody);
	dest.writeString(mSubject);
	dest.writeString(mThread);
	dest.writeString(mFrom);
	dest.writeLong(mSentDate.getTime());
	dest.writeLong(mReceivedDate.getTime());
	dest.writeInt(mRead);
	dest.writeString(mDevices);
	dest.writeInt(mError);
    }

    public long getId() {
	return mId;
    }

    public void setId(long mId) {
	this.mId = mId;
    }

    /**
     * Get the type of the message.
     * @return the type of the message.
     */
    public int getChatType() {
	return mChatType;
    }

    /**
     * Set the type of the message.
     * @param type the type to set
     */
    public void setChatType(int chatType) {
	mChatType = chatType;
    }

    /**
     * Get the body of the message.
     * @return the Body of the message
     */
    public String getBody() {
	return mBody;
    }

    /**
     * Set the body of the message.
     * @param body the body to set
     */
    public void setBody(String body) {
	mBody = body;
    }

    /**
     * Get the subject of the message.
     * @return the subject
     */
    public String getSubject() {
	return mSubject;
    }

    /**
     * Set the subject of the message.
     * @param subject the subject to set
     */
    public void setSubject(String subject) {
	mSubject = subject;
    }

    /**
     * Get the destinataire of the message.
     * @return the destinataire of the message
     */
    public String getTo() {
	return mTo;
    }

    /**
     * Set the destinataire of the message.
     * @param to the destinataire to set
     */
    public void setTo(String to) {
	mTo = to;
    }

    /**
     * Set the from field of the message.
     * @param from the mFrom to set
     */
    public void setFrom(String from) {
	this.mFrom = from;
    }

    /**
     * Get the from field of the message.
     * @return the mFrom
     */
    public String getFrom() {
	return mFrom;
    }

    /**
     * Get the thread of the message.
     * @return the thread
     */
    public String getThread() {
	return mThread;
    }

    /**
     * Set the thread of the message.
     * @param thread the thread to set
     */
    public void setThread(String thread) {
	mThread = thread;
    }

    public Date getSentDate() {
	return mSentDate;
    }

    public void setSentDate(Date sentDate) {
	this.mSentDate = sentDate;
    }

    /**
     * Get the Date of the message.
     * @return if it is a delayed message get the date the message was sended.
     */
    public Date getReceivedDate() {
	return mReceivedDate;
    }

    /**
     * Set the Date of the message.
     * @param date date of the message.
     */
    public void setReceivedDate(Date receivedDate) {
	this.mReceivedDate = receivedDate;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int describeContents() {
	return 0;
    }

    public int getBodyType() {
	return mBodyType;
    }

    public void setBodyType(int bodyType) {
	this.mBodyType = bodyType;
    }

    public String getMsgId() {
	return mMsgId;
    }

    public void setMsgId(String msgId) {
	this.mMsgId = msgId;
    }

    public void setHL(boolean mHL) {
	this.mHL = mHL;
    }

    public boolean isHL() {
	return mHL;
    }

    public String getDevices() {
	return mDevices;
    }

    public void setDevices(String devices) {
	this.mDevices = devices;
    }

    public int getRead() {
	return mRead;
    }

    public void setRead(int readFlag) {
	this.mRead = readFlag;
    }

    public AttachmentInfo getAttchment() {
	return mAttachment;
    }

    public void setAttachment(AttachmentInfo attachment) {
	this.mAttachment = attachment;
    }

    public int getBoxType() {
	return mBoxType;
    }

    public void setBoxType(int boxType) {
	this.mBoxType = boxType;
    }

    public int getStatusType() {
	return mStatusType;
    }

    public void setStatusType(int statusType) {
	this.mStatusType = statusType;
    }

    public int getError() {
	return mError;
    }

    public void setError(int error) {
	this.mError = error;
    }

}
